package com.bocloud.kong.client.impl;

import java.io.IOException;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bocloud.kong.client.OAuth2Client;
import com.bocloud.kong.connector.Connector;
import com.bocloud.kong.connector.FrontConnector;
import com.bocloud.kong.connector.consumers.OAuth2Connector;
import com.bocloud.kong.model.consumers.OAuth2;
import com.bocloud.model.Result;
import com.google.common.collect.Lists;

import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Response;

/**
 * Title: OAuth2ClientImpl Description:
 *
 * @author lkx
 * @version 1.0.0
 * @since 2017-02-15 17:51
 */
@Component
public class OAuth2ClientImpl implements OAuth2Client {

	private static Logger logger = LoggerFactory.getLogger(OAuth2ClientImpl.class);

	@Autowired
	private Connector connector;

	private OAuth2Connector oAuth2Connector;

	private FrontConnector frontConnector;

	@PostConstruct
	private void init() {
		oAuth2Connector = connector.admin(OAuth2Connector.class);
		frontConnector = connector.front(FrontConnector.class);
	}

	@Override
	public OAuth2 add(String consumerId, OAuth2 oAuth2) throws IOException {
		Call<OAuth2> call = oAuth2Connector.add(consumerId, oAuth2);
		Response<OAuth2> response = call.execute();
		if (response.isSuccessful()) {
			return response.body();
		}
		return null;
	}

	@Override
	public List<OAuth2> query(OAuth2 oAuth2) throws IOException {
		Call<ResponseBody> call = oAuth2Connector.rawQuery(oAuth2 == null ? null : oAuth2.toMap());
		Response<ResponseBody> response = call.execute();
		if (response.isSuccessful()) {
			JSONObject object = JSON.parseObject(response.body().string());
			JSONArray array = object.getJSONArray("data");
			return JSON.parseArray(array.toJSONString(), OAuth2.class);
		}
		return Lists.newArrayList();
	}

	@Override
	public List<OAuth2> query(String consumerId, OAuth2 oAuth2) throws IOException {
		Call<ResponseBody> call = oAuth2Connector.query(consumerId, oAuth2 == null ? null : oAuth2.toMap());
		Response<ResponseBody> response = call.execute();
		if (response.isSuccessful()) {
			JSONObject object = JSON.parseObject(response.body().string());
			JSONArray array = object.getJSONArray("data");
			return JSON.parseArray(array.toJSONString(), OAuth2.class);
		}
		return Lists.newArrayList();
	}

	@Override
	public OAuth2 queryOne(String consumerId, String oauth2Id) throws IOException {
		Call<OAuth2> call = oAuth2Connector.queryOne(consumerId, oauth2Id);
		Response<OAuth2> response = call.execute();
		if (response.isSuccessful()) {
			return response.body();
		}
		return null;
	}

	@Override
	public OAuth2 update(String consumerId, String oauth2Id, OAuth2 oAuth2) throws IOException {
		Call<OAuth2> call = oAuth2Connector.update(consumerId, oauth2Id, oAuth2);
		Response<OAuth2> response = call.execute();
		if (response.isSuccessful()) {
			return response.body();
		}
		return null;
	}

	@Override
	public void delete(String consumerId, String oauth2Id) throws IOException {
		oAuth2Connector.delete(consumerId, oauth2Id).execute();
	}

	@Override
	public Result authorize(Map<String, String> params, String host) {
		Call<ResponseBody> call = frontConnector.authorize(params, host);
		try {
			Response<ResponseBody> response = call.execute();
			if (response.isSuccessful()) {
				JSONObject object = JSON.parseObject(response.body().string());
				return new Result(true, object.getString("redirect_uri"));
			}
			return new Result(true, response.errorBody().string());
		} catch (IOException e) {
			logger.info("{}", e);
			return new Result(false, e.getMessage());
		}
	}

	@Override
	public Integer totalSize(OAuth2 oAuth) throws IOException {
		Call<ResponseBody> call = oAuth2Connector.rawQuery(oAuth == null ? null : oAuth.toMap());
		Response<ResponseBody> response = call.execute();
		if (response.isSuccessful()) {
			JSONObject object = JSON.parseObject(response.body().string());
			return object.getInteger("total");
		}
		return null;
	}
}
